package com.hyt.it.ogt.common.utils;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.*;

/**
 * @author huangwu
 * @ClassName: ExecutorPoolUtil
 * @Description: 线程池工具类
 * @date 2022年03月10日 下午1:51:56
 */
public class ExecutorPoolUtil {
    private static final Logger logger = LoggerFactory.getLogger(ExecutorPoolUtil.class);
    private static ThreadPoolExecutor executorService = null;
    private static int THREAD_POOL_SIZE = 10;
    private static volatile Boolean hasInit = Boolean.FALSE;
    private static volatile Boolean fileCreatePoolHasInit = Boolean.FALSE;
    private static final ThreadPoolTaskExecutor EXECUTOR;
    private static ThreadPoolTaskExecutor CREATEFILEEXECUTOR = null;


    private ExecutorPoolUtil() {

    }

    static {
        //initExecutorService();
        EXECUTOR = new ThreadPoolTaskExecutor();
        // 线程池维护线程的最少数量
        EXECUTOR.setCorePoolSize(10);
        // 线程池所使用的缓冲队列
        EXECUTOR.setQueueCapacity(10000);
        // 线程池维护线程的最大数量
        EXECUTOR.setMaxPoolSize(100);
        // 线程池维护线程所允许的空闲时间
        EXECUTOR.setKeepAliveSeconds(1000);
        EXECUTOR.initialize();
    }

    /**
     * 执行带返回任务的异步线程
     */
    public static <T> Future<T> submit(Callable<T> callable) {
        ThreadPoolTaskExecutor poolTaskExecutor = EXECUTOR;
        return poolTaskExecutor.submit(callable);
    }

    /**
     * 执行带返回任务的异步线程
     */
    public static <T> Future<T> submitFileExcure(Callable<T> callable) {
        ThreadPoolTaskExecutor poolTaskExecutor = CREATEFILEEXECUTOR;
        return poolTaskExecutor.submit(callable);
    }

    private static void initExecutorService() {
        try {
            ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("pjservice-pool-%d").build();
            executorService = new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<>(1024),
                    threadFactory,
                    new ThreadPoolExecutor.DiscardPolicy()); // 如果队列超过了1024则直接抛弃请求，也不抛出异常了
            hasInit = true;
        } catch (Exception e) {
            logger.error("初始化线程池失败", e);
        }

    }

    public static ExecutorService getExecutorService() {
        // 解决在初始化的时候没有初始成功
        if (hasInit) {
            int activeCount = ((ThreadPoolExecutor) executorService).getActiveCount();
            int poolSize = ((ThreadPoolExecutor) executorService).getMaximumPoolSize();
            if (Double.valueOf(String.valueOf(activeCount)) / poolSize >= 0.8) {
                logger.warn("PreExecutorServiceBLL 活跃线程数已达到80%，是否调整");
            }
            return executorService;
        } else {
            initExecutorService();
        }
        return executorService;

    }


    public static ThreadPoolTaskExecutor getPoolTaskExecutor() {
        return EXECUTOR;
    }

    public static ThreadPoolTaskExecutor getFileCreatePoolTaskExecutor() {
        if (!fileCreatePoolHasInit) {
            try {
                // initExecutorService();
                CREATEFILEEXECUTOR = new ThreadPoolTaskExecutor();
                // 线程池维护线程的最少数量
                CREATEFILEEXECUTOR.setCorePoolSize(10);
                // 线程池所使用的缓冲队列
                CREATEFILEEXECUTOR.setQueueCapacity(1000);
                // 线程池维护线程的最大数量
                CREATEFILEEXECUTOR.setMaxPoolSize(100);
                // 线程池维护线程所允许的空闲时间
                CREATEFILEEXECUTOR.setKeepAliveSeconds(1000);
                CREATEFILEEXECUTOR.initialize();

                fileCreatePoolHasInit = true;
            } catch (Exception e) {
                logger.error("初始化文件执行线程池失败", e);
            }
        }
        return CREATEFILEEXECUTOR;
    }
}
